package ru.ifmo.metopt;

import ru.ifmo.metopt.abstracts.Function;
import ru.ifmo.metopt.abstracts.MultipleDimensionSolver;
import ru.ifmo.metopt.abstracts.RestrictedTaskSolver;

/**
 * @author avhaliullin
 */
public class InternalPointSolver implements RestrictedTaskSolver {
    private final double k;
    private final MultipleDimensionSolver solver;

    public InternalPointSolver(double k, MultipleDimensionSolver solver) {
        this.k = k;
        this.solver = solver;
    }

    private boolean checkRestrictions(Function[] restrictions, double[] point) {
        for (Function restriction : restrictions) {
            if (restriction.f(point) < 0) {
                return false;
            }
        }
        return true;
    }

    @Override
    public double[] solve(Function f, double[] initial, Function... restrictions) {
        InternalPointExtension extension = new InternalPointExtension(f, restrictions);
        double[] result = initial;
        do {
            result = solver.solve(extension, result);
            extension.setP(extension.getP() * k);
        } while (!checkRestrictions(restrictions, result));
        return result;
    }

}
